package com.mdoya.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mdoya.domain.*;
import com.mdoya.mapper.OrderDetailMapper;
import com.mdoya.mapper.OrderMapper;
import com.mdoya.query.BaseQuery;
import com.mdoya.service.*;
import com.mdoya.utils.ThreadLocalContextUtils;
import com.mdoya.vo.OrderVo;
import com.sun.org.apache.xpath.internal.operations.Or;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * @author mdoya
 * @version 1.0
 * @description:
 */
@Scope("singleton")
@Transactional(propagation = Propagation.REQUIRED)
@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private AddressBookService addressBookService;
    @Autowired
    private ShoppingCartService shoppingCartService;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private UserService userService;
    @Autowired
    private OrderDetailService orderDetailService;

    /**
     * 提交订单
     *
     * @param orders
     * @return
     */
    @Override
    public Integer add(Orders orders) {
        System.err.println(orders);
        // 1. 添加订单表
        orders.setId(IdWorker.getId()); // mybatisPlus 手动生成id注解
        orders.setOrderTime(LocalDateTime.now()); // 订单时间
        orders.setUserId(ThreadLocalContextUtils.getUserLongId()); // 用户id
        orders.setCheckoutTime(LocalDateTime.now());
        orders.setStatus(1); // 订单状态
        orders.setNumber(UUID.randomUUID().toString().replace("-", ""));
        // 找用户订单收货地址
        AddressBook addressBook = addressBookService.getById(orders.getAddressBookId());
        orders.setAddress(
                addressBook.getProvinceName() != null ? addressBook.getProvinceName() : "" +
                        addressBook.getCityName() != null ? addressBook.getCityName() : "" +
                        addressBook.getDistrictName() != null ? addressBook.getDistrictName() : "" +
                        addressBook.getDetail() != null ? addressBook.getDetail() : ""
        );
        /*orders.setAddress(addressBook.getProvinceName() != null ? addressBook.getProvinceName() : "" +
                addressBook.getCityName() != null ? addressBook.getCityName() : "" +
                addressBook.getDistrictName() != null ? addressBook.getDistrictName() : "" +
                addressBook.getDetail() != null ? addressBook.getDetail() : "");*/
        orders.setAddress(addressBook.getDetail());
        orders.setConsignee(addressBook.getConsignee());
        // 找用户 填充手机号码
        User user = userService.findIdUser(ThreadLocalContextUtils.getUserLongId());
        orders.setPhone(user.getPhone());
        orders.setUserName(user.getName());

        int rows = orderMapper.insert(orders);
        // 找用户购买菜品数量
        List<ShoppingCart> shoppingCartList = shoppingCartService.findUserShoppinCar(ThreadLocalContextUtils.getUserLongId());

        // 2. 添加订单详情表
        List<Integer> orderDetailRowsList = shoppingCartList.stream().map((item) -> {
            OrderDetail orderDetail = new OrderDetail();
            BeanUtils.copyProperties(item, orderDetail, "id");
            orderDetail.setOrderId(orders.getId());
            int rows2 = 0;
            rows2 += orderDetailMapper.insert(orderDetail);
            return rows2;
        }).collect(Collectors.toList());


        // 3. 清空购物车
        if (rows > 0 && orderDetailRowsList.size() == shoppingCartList.size()) {
            shoppingCartService.cleanShoppingCar(ThreadLocalContextUtils.getUserLongId());
        }
        return rows;
    }

    /**
     * 分页查询
     *
     * @param baseQuery 分页参数
     * @return
     */
    @Override
    public IPage<OrderVo> selectPage(BaseQuery baseQuery) {
        // 订单数据
        IPage<Orders> ordersPage = new Page<>(baseQuery.getPage(), baseQuery.getPageSize());
        LambdaQueryWrapper<Orders> queryWrapper = new LambdaQueryWrapper<>();
        // 订单号查询  考虑订单号是唯一 所以等价查询
        queryWrapper.eq(baseQuery.getNumber() != null, Orders::getNumber, baseQuery.getNumber());
        // 时间范围查询
        queryWrapper.gt(baseQuery.getBeginTime() != null, Orders::getOrderTime, baseQuery.getBeginTime());
        queryWrapper.lt(baseQuery.getEndTime() != null, Orders::getCheckoutTime, baseQuery.getEndTime());

        orderMapper.selectPage(ordersPage, queryWrapper);
        // vo封装数据
        IPage<OrderVo> orderVoPage = new Page<>();
        orderVoPage.setTotal(ordersPage.getTotal());
        List<OrderVo> orderVoList = ordersPage.getRecords().stream().map((item) -> {
            OrderVo orderVo = new OrderVo();
            BeanUtils.copyProperties(item, orderVo);
            // 订单详情
            List<OrderDetail> detailList = orderDetailService.findOrderId(item.getId());
            orderVo.setFlavors(detailList);
            return orderVo;
        }).collect(Collectors.toList());
        // 封装vo数据
        orderVoPage.setRecords(orderVoList);

        return orderVoPage;
    }

    /**
     * 前端最新订单查询
     *
     * @param baseQuery
     * @return
     */
    @Override
    public IPage<OrderVo> selectPageIndex(BaseQuery baseQuery) {

        IPage<Orders> ordersPage = new Page<>(baseQuery.getPage(), baseQuery.getPageSize());
        LambdaQueryWrapper<Orders> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(baseQuery.getUserId() != null, Orders::getUserId, baseQuery.getUserId());
        queryWrapper.orderByDesc(Orders::getOrderTime);
        orderMapper.selectPage(ordersPage,queryWrapper);

        // 封装数据
        IPage<OrderVo> orderVoPage = new Page<>();
        orderVoPage.setTotal(ordersPage.getTotal());
        List<OrderVo> orderVoList = ordersPage.getRecords().stream().map((item) -> {
            OrderVo orderVo = new OrderVo();
            BeanUtils.copyProperties(item, orderVo);
            List<OrderDetail> orderDetailList = orderDetailService.findOrderId(item.getId());
            orderVo.setFlavors(orderDetailList);
            return orderVo;
        }).collect(Collectors.toList());
        // 封装数据
        orderVoPage.setRecords(orderVoList);
        return orderVoPage;
    }
}
